using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using HappySprite;

namespace HappyInvaders
{
    class ShelterBitmap
    {
        static readonly byte[] map =
            {
                0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
                0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
                0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
                0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1
            };

        BitArray bitArray = new BitArray(24 * 16);
        bool hasChanged = true;

        byte damageCounter;
        byte[] damageX = new byte[255];
        byte[] damageY = new byte[255];

        public ShelterBitmap()
        {
            Reset();

            for (int i = 0; i < 255; i++)
            {
                damageX[i] = (byte)Global.Random.Next(4);
                damageY[i] = (byte)Global.Random.Next(6);
            }
        }

        public bool HasChanged
        {
            get { return hasChanged; }
            set { hasChanged = value; }
        }

        public BitArray GetBitArray()
        {
            return bitArray;
        }

        public bool CheckBomb(int x, int y)
        {
            // Crawl down the rows from 15 to y, if the cell is true a collision has occured
            for (int i = 15; i >= y; i--)
            {
                if (GetValue(x, i))
                {
                    ErodeShelter(x, i);
                    return true;
                }
            }

            return false;
        }

        public bool CheckBullet(int x, int y)
        {
            // Crawl up the rows from 0 to y, if the cell is true then a collision has occured
            for (int i = 0; i <= y; i++)
            {
                if (GetValue(x, i))
                {
                    ErodeShelter(x, i);
                    return true;
                }
            }

            return false;
        }

        public void ClearRange(int startX, int endX, int startY, int endY)
        {
            for (int i = startX; i <= endX; i++)
                for (int j = startY; j <= endY; j++)
                    ClearValue(i, j);

            HasChanged = true;
        }

        public void Reset()
        {
            for (int i = 0; i < 24 * 16; i++)
                bitArray.Set(i, map[i] != 0);

            HasChanged = true;
        }

        bool GetValue(int x, int y)
        {
            return bitArray[x + 24 * (15 - y)];
        }

        void ClearValue(int x, int y)
        {
            bitArray[x + 24 * (15 - y)] = false;
        }

        void ErodeShelter(int x, int y)
        {
            for (int i = 0; i < 25; i++)
            {
                int cx = x + damageX[damageCounter + i] - 2;
                int cy = y + damageY[damageCounter + i + 1] - 3;

                if (cx < 0 || cx > 23 || cy < 0 || cy > 15)
                    continue;

                ClearValue(cx, cy);
            }

            damageCounter += 20;
            if (damageCounter > 255 - 26) damageCounter = 0;

            HasChanged = true;
        }
    }
}
